package core

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"os"
	"strings"
)

type BoxHeader struct {
	Size uint32
	FourccType [4]byte
	Size64 uint64
}

type Mp4 struct {}

func (m Mp4)GetMp4Duration(filepath string) (duration string,second int , err error) {
	// 打开目录文件
	file, err := os.Open(filepath)
	if err != nil {
		if strings.Contains(err.Error(), "no such file or diectory") {
			return "",0 , errors.New("文件不存在")
		}
		return "",0 , err
	}
	defer func(file *os.File) {
		if err = file.Close(); err != nil {
			fmt.Println("file close fail err : ", err)
		}
	}(file)

	var (
		info      = make([]byte, 0x10)
		boxHeader BoxHeader
		offset    int64 = 0
	)

	// 获取结构便宜
	for{
		_, err = file.ReadAt(info, offset)
		if err != nil {
			return
		}

		boxHeader = m.getHeaderBoxInfo(info)
		fourccType := m.getFourccType(boxHeader)
		if fourccType == "moov" {
			break
		}
		// 一部分mp4 mdat尺寸过大需要特殊处理
		if fourccType == "mdat" {
			if boxHeader.Size == 1 {
				offset += int64(boxHeader.Size)
				continue
			}
		}

		offset += int64(boxHeader.Size)
	}

	moveStartBytes := make([]byte, 0x100)
	_,err = file.ReadAt(moveStartBytes, offset)
	if err != nil {
		return
	}

	timeScaleOffset := 0x1C
	durationOffset := 0x20
	timeScale := binary.BigEndian.Uint32(moveStartBytes[timeScaleOffset : timeScaleOffset + 4])
	d := binary.BigEndian.Uint32(moveStartBytes[durationOffset : durationOffset + 4])
	second = int(d / timeScale)
	return ResolveTime(second),second, nil
}

func (m Mp4)getHeaderBoxInfo(data []byte) (boxHeader BoxHeader) {
	buf := bytes.NewBuffer(data)
	_ = binary.Read(buf, binary.BigEndian, &boxHeader)
	return
}

func (m Mp4)getFourccType(boxHeader BoxHeader) (fourccType string) {
	fourccType = string(boxHeader.FourccType[:])
	return
}
